//给你一个字符串 s ，请你去除字符串中重复的字母，使得每个字母只出现一次。需保证 返回结果的字典序最小（要求不能打乱其他字符的相对位置）。 
//
// 注意：该题与 1081 https://leetcode-cn.com/problems/smallest-subsequence-of-distinct
//-characters 相同 
//
// 
//
// 示例 1： 
//
// 
//输入：s = "bcabc"
//输出："abc"
// 
//
// 示例 2： 
//
// 
//输入：s = "cbacdcbc"
//输出："acdb" 
//
// 
//
// 提示： 
//
// 
// 1 <= s.length <= 104 
// s 由小写英文字母组成 
// 
// Related Topics 栈 贪心 字符串 单调栈 
// 👍 549 👎 0


package leetcode.editor.cn;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;

//Java：去除重复字母
public class P316RemoveDuplicateLetters{
    public static void main(String[] args) {
        Solution solution = new P316RemoveDuplicateLetters().new Solution();
        // TO TEST
        System.out.println(solution.removeDuplicateLetters("cbacdcbc"));
    }
    //leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public String removeDuplicateLetters(String s) {
        Stack<Character> stack = new Stack<>();
        HashMap<Character,Integer> countMap = new HashMap<>();
        Set<Character> set = new HashSet<>();
        StringBuilder res = new StringBuilder();

        for(Character c : s.toCharArray()){
            countMap.put(c,countMap.getOrDefault(c,0)+1);
        }


        for(Character c : s.toCharArray()){
            countMap.put(c,countMap.get(c)-1);

            if(set.contains(c)){
                continue;
            } else {
                set.add(c);
                if(!stack.isEmpty()){
                    Character temp = stack.peek();
                    while(!stack.isEmpty() && temp > c && countMap.get(temp)>0){
                        stack.pop();
                        set.remove(temp);
                        if(!stack.isEmpty()){
                            temp = stack.peek();
                        }
                    }
                    stack.add(c);
                } else {
                    stack.add(c);
                }
            }
        }


        for(Character c : stack){
            res.append(c);
        }
        return res.toString();
    }

}
//leetcode submit region end(Prohibit modification and deletion)

}